package functional

/**
  decorator模式，即middleware，优化
*/

import (
	"fmt"
	"reflect"
)

func foo(a, b, c int) int {
	fmt.Printf("%d, %d, %d \n", a, b, c)
	return a + b + c
}

func bar(a, b string) string {
	fmt.Printf("%s, %s \n", a, b)
	return a + b
}

//
func Decorator(decoPtr, fn interface{}) (err error) {
	var decoratedFunc, targetFunc reflect.Value
	decoratedFunc = reflect.ValueOf(decoPtr).Elem()
	targetFunc = reflect.ValueOf(fn)
	v := reflect.MakeFunc(targetFunc.Type(),
		func(in []reflect.Value) (out []reflect.Value) {
			fmt.Println("before")
			out = targetFunc.Call(in)
			fmt.Println("after")
			return
		})
	decoratedFunc.Set(v)
	return
}

/**
  https://coolshell.cn/articles/17929.html
*/

func GetDecorator() {
	//type MyFoo func(int, int, int) int
	//var myFoo MyFoo
	//_ = Decorator(&myFoo, foo)
	//myFoo(1, 2, 3)
	mybar := bar
	_ = Decorator(&mybar, bar)
	mybar("hello,", "world!")
}
